# coding=gbk
"""
Created on 2016/6/2 0002

@author: Blunce

@about:

"""
import matplotlib.pyplot as plt
import numpy as np


class ECG_Simulator:
    def __init__(self, x=np.arange(0, 2, 0.01), rate=72):
        self.__rate = rate  # Heart beat
        self.__t = x
        self.__li = 30.0 / self.__rate

        self.__a_pwav = 0.25  # P wave          0.25mV
        self.__d_pwav = 0.09  # P interval      0.09s
        self.__t_pwav = 0.16  # P-R interval    0.16s

        self.__a_qwav = 0.025  # Q wave         0.025mV
        self.__d_qwav = 0.066  # Q wave
        self.__t_qwav = 0.166

        self.__a_qrswav = 1.6
        self.__d_qrswav = 0.11

        self.__a_swav = 0.25
        self.__d_swav = 0.066
        self.__t_swav = 0.09

        self.__a_twav = 0.35  # T wave          0.35mV
        self.__d_twav = 0.142
        self.__t_twav = 0.2

        self.__a_uwav = 0.035
        self.__d_uwav = 0.0476
        self.__t_uwav = 0.433

    def setPwavPar(self, a_pwav, d_pwav, t_pwav):
        self.__a_pwav = a_pwav
        self.__d_pwav = d_pwav
        self.__t_pwav = t_pwav

    def setQwavPar(self, a_qwav, d_qwav, t_qwav):
        self.__a_qwav = a_qwav
        self.__d_qwav = d_qwav
        self.__t_qwav = t_qwav

    def setQRSwavPar(self, a_qrswav, d_qrswav):
        self.__a_qrswav = a_qrswav
        self.__d_qrswav = d_qrswav

    def setSwavPar(self, a_swav, d_swav, t_swav):
        self.__a_swav = a_swav
        self.__d_swav = d_swav
        self.__t_swav = t_swav

    def setTwavPar(self, a_twav, d_twav, t_twav):
        self.__a_twav = a_twav
        self.__d_twav = d_twav
        self.__t_twav = t_twav

    def setUwavPar(self, a_uwav, d_uwav, t_uwav):
        self.__a_uwav = a_uwav
        self.__d_uwav = d_uwav
        self.__t_uwav = t_uwav

    def __p_wav(self):
        l = self.__li
        a = self.__a_pwav
        x = self.__t + self.__t_pwav
        b = (2 * l) / self.__d_pwav
        n = 100
        p1 = 1.0 / l
        p2 = 0
        for i in range(1, n + 1):
            harm1 = (((np.sin((np.pi / (2 * b)) * (b - (2 * i)))) / (
                b - (2 * i)) + (
                          np.sin((np.pi / (2 * b)) * (b + (2 * i)))) / (
                          b + (2 * i))) * (2 / np.pi)) * np.cos(
                (i * np.pi * x) / l)
            p2 += harm1
        p_wav1 = p1 + p2
        self.__pwav = a * (p1 + p2)

    def __q_wav(self):
        l = self.__li
        x = self.__t + self.__t_qwav
        a = self.__a_qwav
        b = (2 * l) / self.__d_qwav
        n = 100
        q1 = (a / (2 * b)) * (2 - b)
        q2 = 0
        for i in range(1, n + 1):
            harm5 = (((2 * b * a) / (i * i * np.pi * np.pi)) * (
                1 - np.cos((i * np.pi) / b))) * np.cos((i * np.pi * x) / l)
            q2 += harm5
        self.__qwav = 1 * (q1 + q2)

    def __qrs_wav(self):
        l = self.__li
        a = self.__a_qrswav
        b = (2 * l) / self.__d_qrswav
        n = 100
        qrs1 = (a / (2 * b)) * (2 - b)
        qrs2 = 0
        for i in range(1, n + 1):
            harm = (((2 * b * a) / (i * i * np.pi * np.pi)) * (
                1 - np.cos((i * np.pi) / b))) * np.cos(
                (i * np.pi * self.__t) / l)
            qrs2 += harm
        self.__qrswav = qrs1 + qrs2

    def __s_wav(self):
        l = self.__li
        x = self.__t - self.__t_swav
        a = self.__a_swav
        b = (2 * l) / self.__d_swav
        n = 100
        s1 = (a / (2 * b)) * (2 - b)
        s2 = 0
        for i in range(1, n + 1):
            harm3 = (((2 * b * a) / (i * i * np.pi * np.pi)) * (
                1 - np.cos((i * np.pi) / b))) * np.cos((i * np.pi * x) / l)
            s2 += harm3
        self.__swav = -1 * (s1 + s2)

    def __t_wav(self):
        l = self.__li
        a = self.__a_twav
        x = self.__t - self.__t_twav - 0.045
        b = (2 * l) / self.__d_twav
        n = 100
        t1 = 1 / l
        t2 = 0
        for i in range(1, n + 1):
            harm2 = (
                        ((np.sin((np.pi / (2 * b)) * (b - (2 * i)))) / (
                            b - (2 * i)) + (
                             np.sin((np.pi / (2 * b)) * (b + (2 * i)))) / (
                             b + (2 * i))) * (
                            2 / np.pi)) * np.cos(
                (i * np.pi * x) / l)
            t2 += harm2
        self.__twav = a * (t1 + t2)

    def __u_wav(self):
        l = self.__li
        a = self.__a_uwav
        x = self.__t - self.__t_uwav
        b = (2 * l) / self.__d_uwav
        n = 100
        u1 = 1 / l
        u2 = 0
        for i in range(1, n + 1):
            harm4 = (
                        ((np.sin((np.pi / (2 * b)) * (b - (2 * i)))) / (
                            b - (2 * i)) + (
                             np.sin((np.pi / (2 * b)) * (b + (2 * i)))) / (
                             b + (2 * i))) * (2 / np.pi)) * np.cos(
                (i * np.pi * x) / l)
            u2 += harm4
        self.__uwav = a * (u1 + u2)

    def simulate(self):
        self.__p_wav()
        self.__q_wav()
        self.__qrs_wav()
        self.__s_wav()
        self.__t_wav()
        self.__u_wav()
        self.__ecg = self.__pwav \
                     # + self.__qwav \
                     # + self.__qrswav \
                     # + self.__uwav \
                     # + self.__swav \
                     # + self.__twav

        self.__ecg=self.__ecg[50:135]
        return self.__ecg

    def draw(self):
        plt.plot(self.__ecg)
        plt.show()


if __name__ == '__main__':
    print "**************start**************\n\n"

    ecg = ECG_Simulator()
    ecg.simulate()
    ecg.draw()

    print "\n\n**************end**************"
